import type { RESOURCE_NAME } from '../../../types/interfaces'
import { logger } from '../../../types/constants'
import { SYMBOLS } from '../../../types/interfaces'
import { ToolKit } from '../toolkit'
import { sha256 } from './crypto'

export class ResourceUtils {
  /**
   * 获取资源文本
   * @param resourceName 资源名称
   * @returns 资源文本
   */
  static getResourceText(resourceName: RESOURCE_NAME): string {
    return GM_getResourceText(resourceName)
  }

  /**
   * 获取资源 URL
   * @param resourceName 资源名称
   * @returns 资源 URL
   */
  static getResourceURL(resourceName: RESOURCE_NAME): string {
    return GM_getResourceURL(resourceName)
  }

  /**
   * 生成资源完整性哈希值
   * @param resourceName 资源名称
   * @returns 资源完整性哈希值
   */
  static async generateResourceIntegrity(resourceName: RESOURCE_NAME): Promise<string> {
    const resourceText = this.getResourceText(resourceName)
    const sha256Hash = await sha256(resourceText)
    return `sha256-${sha256Hash}`
  }

  /**
   * 检查资源完整性哈希值是否存在于 URL 中
   * @param resourceName 资源名称
   * @param url 资源 URL
   * @returns 是否存在完整性哈希值
   */
  static async checkResourceIntegrity(resourceName: RESOURCE_NAME, url: string): Promise<boolean> {
    try {
      const integrity = await this.generateResourceIntegrity(resourceName)

      const integrityChecks = [
        // 1. 直接包含在 URL 中
        url.includes(integrity),
        // 2. URL 编码版本
        url.includes(encodeURIComponent(integrity)),
        // 3. Base64 编码版本
        url.includes(btoa(integrity)),
        // 4. 哈希值部分匹配（防止截断）
        new RegExp(integrity.slice(0, 16)).test(url),
      ]

      const isIntegrityValid = integrityChecks.some(check => check)

      if (!isIntegrityValid) {
        logger.warn(`[IntegrityCheck] [resource] ${resourceName} 资源完整性检查未通过，请更新资源 URL 中的完整性哈希值`, {
          url,
          expected: integrity,
          actual: ToolKit.browser.url.extractIntegrityFromUrl(url)?.value || '未知',
        })
      }
      else {
        logger.success(`[IntegrityCheck] [resource] ${SYMBOLS.STATUS.SUCCESS} ${resourceName} 资源完整性检查通过`)
      }

      return isIntegrityValid
    }
    catch (error) {
      logger.error(`[IntegrityCheck] [resource] ${resourceName} 资源完整性检查失败:`, error)
      return false
    }
  }
}
